package config

import (
	"fmt"
	"time"

	"github.com/bernos/go-retry"
	_ "github.com/go-sql-driver/mysql"
	"github.com/go-xorm/core"
	"github.com/go-xorm/xorm"
	"gitlab.gaodun.com/golib/gderror"
	"permission/vigo_loger"
)

var mySqlConfig, _ = GetMySQLConfig()
var logConfig, _ = GetLogConfig()

var Engine, errs = NewEngine(mySqlConfig)
var LogEngine, lerrs = NewEngine(logConfig)

func GetDBEng(engine *xorm.Engine, sqlConfig MySQLDriver) func() (interface{}, error) {
	return func() (interface{}, error) {
		err := engine.Ping()
		if err != nil {
			engine, _ = NewEngine(sqlConfig)
			return nil, err
		}
		return nil, nil
	}
}

func RetryLog(format string, v ...interface{}) {
	vigo_loger.AddGrayLog(fmt.Sprintf(format, v...))
}

// 初始化返回 engine
var InitEng = func() (*xorm.Engine, error) {
	if errs != nil {
		vigo_loger.AddGrayLog("db ping() err : " + errs.Error())
		return Engine, errs
	}
	r := retry.Retry(GetDBEng(Engine, mySqlConfig),
		retry.MaxRetries(5),
		retry.BaseDelay(time.Millisecond*200),
		retry.Log(RetryLog))
	_, err := r()
	if err != nil {
		vigo_loger.AddGrayLog(err.(error).Error())
		return Engine, err.(error)
	}
	return Engine, nil
}

var InitLogEng = func() (*xorm.Engine, error) {
	if errs != nil {
		vigo_loger.AddGrayLog("db ping() err : " + errs.Error())
		return LogEngine, lerrs
	}
	r := retry.Retry(GetDBEng(LogEngine, logConfig),
		retry.MaxRetries(5),
		retry.BaseDelay(time.Millisecond*200),
		retry.Log(RetryLog))
	_, err := r()
	if err != nil {
		vigo_loger.AddGrayLog(err.(error).Error())
		return LogEngine, err.(error)
	}
	return LogEngine, nil
}

func NewEngine(configInfo MySQLDriver) (*xorm.Engine, error) {
	var eng xorm.Engine
	if err != nil {
		return &eng, gderror.New(err.Error())
	}
	engine, err := xorm.NewEngine(configInfo.DriverName, configInfo.DriverDns)
	vigo_loger.AddGrayLog("start : " + configInfo.DriverDns)
	if err != nil {
		vigo_loger.AddGrayLog("db err : " + err.Error() + configInfo.DriverName + configInfo.DriverDns)
		panic(err)
	}
	logger := xorm.NewSimpleLogger(vigo_loger.GraySql)
	logger.ShowSQL(true)
	logger.SetLevel(core.LOG_INFO)
	engine.Logger().SetLevel(core.LOG_ERR)
	engine.SetLogger(logger)
	engine.ShowSQL(true)
	engine.ShowExecTime(true)
	// 设置映射关系
	engine.SetMapper(core.SameMapper{})
	err = engine.Ping()
	if err != nil {
		vigo_loger.AddGrayLog("db ping() err : " + err.Error() + configInfo.DriverName + configInfo.DriverDns)
		//panic(err)
	}
	tmpDb := engine.DB()
	tmpDb.SetConnMaxLifetime(1 * time.Hour)
	engine.SetMaxIdleConns(50)
	engine.SetMaxOpenConns(200)
	return engine, nil
}
